/*!
* @file    button.c
* @version v1.0
* @date    2018-02-05
* @author  苏勇 suyong_yq@126.com
* @brief   基于定时器和GPIO实现简单的检测按键的功能
*/

#include "button.h"
#include "fsl_gpio.h"

#define BTN_TIMER_FILTER_COUNT  4U /* 按键时域滤波级数 */
#define BTN_COUNT_MAX  3U
const uint32_t cBtnGpioPins[BTN_COUNT_MAX][2] =
{
    /* PORT, PinIdx*/
    {  1U,   11U  }, /* K0: PIO1_11. */
    {  0U,   5U   }, /* K1: PIO0_5 . */
    {  1U,   16U  }  /* K2: PIO1_16. */
};

/* 记录按键是否按下的状态 */
volatile bool bBtnPressed[BTN_COUNT_MAX];
volatile uint32_t gBtnPressedCounter[BTN_COUNT_MAX];
volatile bool bBtnPressedPre[BTN_COUNT_MAX];

void BTN_Init(void)
{
    uint32_t i;
    gpio_pin_config_t GpioPinConfigStruct;

    GpioPinConfigStruct.pinDirection = kGPIO_DigitalInput;
    for (i = 0U; i < BTN_COUNT_MAX; i++)
    {
        /* 设定按键引脚为GPIO输入 */
        GPIO_PinInit(GPIO, cBtnGpioPins[i][0], cBtnGpioPins[i][1], &GpioPinConfigStruct);
        if (0U == GPIO_ReadPinInput(GPIO, cBtnGpioPins[i][0], cBtnGpioPins[i][1]))
        {
            bBtnPressed[i] = true;
            gBtnPressedCounter[i] = 1U;
        }
        else
        {
            bBtnPressed[i] = false;
            gBtnPressedCounter[i] = 0U;
        }
        bBtnPressedPre[i] = bBtnPressed[i];
    }
}

/* 仅仅捕获按键释放的瞬间 */
void BTN_WaitBlocking(uint32_t btnIdx)
{
    bBtnPressedPre[btnIdx] = bBtnPressed[btnIdx];
    while (1)
    {
        if (bBtnPressedPre[btnIdx] != bBtnPressed[btnIdx])
        {
            if ( (bBtnPressedPre[btnIdx]) && (!bBtnPressed[btnIdx]) )
            {
                break;
            }
            else
            {
                bBtnPressedPre[btnIdx] = bBtnPressed[btnIdx];
            }
        }
    }
}

/* 这个函数将处于定时器服务程序中周期调用
 * 对按键的采样值进行滤波处理，消除抖动
 */
void BTN_WaitBlockingHook(void)
{
    uint32_t i;
    uint32_t gpioValue;

    for (i = 0U; i < BTN_COUNT_MAX; i++)
    {
        gpioValue = GPIO_ReadPinInput(GPIO, cBtnGpioPins[i][0], cBtnGpioPins[i][1]);
        /* 采样检测按下边沿 */
        if (   (!bBtnPressed[i]) /* 记录为松开状态 */
            && (0U == gpioValue) /* 准备向按下状态跃迁 */
            )
        {
            if (gBtnPressedCounter[i] < BTN_TIMER_FILTER_COUNT)
            {
                gBtnPressedCounter[i]++;
            }
            else
            {
                bBtnPressed[i] = true;
                gBtnPressedCounter[i] = 0U;
            }
        }
        else if ( bBtnPressed[i] /* 记录为按下状态 */
               && (1U == gpioValue) /* 准备向松开状态跃迁 */
            )
        {
            if (gBtnPressedCounter[i] < BTN_TIMER_FILTER_COUNT)
            {
                gBtnPressedCounter[i]++;
            }
            else
            {
                bBtnPressed[i] = false;
                gBtnPressedCounter[i] = 0U;
            }
        }
    }
}

/* EOF. */

